package com.gxa.learning.pc.service.impl;

import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import com.gxa.learning.core.common.ExceptionCode;
import com.gxa.learning.core.exception.BusinessException;
import com.gxa.learning.core.pojo.ExamineApproval;
import com.gxa.learning.core.pojo.FlowPathNode;
import com.gxa.learning.core.pojo.UserRole;
import com.gxa.learning.core.service.impl.BaseServiceImpl;
import com.gxa.learning.pc.mapper.ExamineApprovalMapper;
import com.gxa.learning.pc.mapper.FlowPathNodeMapper;
import com.gxa.learning.pc.mapper.UserRoleMapper;
import com.gxa.learning.pc.service.ExamineApprovalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author lijianmin
 * @date 2021/12/03  10:20:02
 */
@Service("examineApprovalService")
@Transactional(rollbackFor = {Throwable.class}, propagation = Propagation.REQUIRED)
public class ExamineApprovalServiceImpl extends BaseServiceImpl<ExamineApproval> implements ExamineApprovalService {

    @Resource
    private ExamineApprovalMapper examineApprovalMapper;

    @Resource
    private FlowPathNodeMapper flowPathNodeMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 根据条件搜索的方法
     *
     * @param name             流程名称
     * @param state            流程状态
     * @param type             流程类型
     * @param departmentName   所属部门
     * @param creationTime     生效日期
     * @param uploadPeopleName 上传人
     * @param page             页码
     * @param size             每页数据量
     * @return 返回查询到的集合并根据分页条件分页
     */
    @Override
    public PageInfo<Map<String, Object>> selectByLikes(String name, Integer state, String type, String departmentName, Date creationTime, String uploadPeopleName, Integer page, Integer size) throws BusinessException {
        if (page == null || size == null) {
            page = 1;
            size = 10;
        }
        if (page < 1 || size < 1) {
            throw new BusinessException(ExceptionCode.PAGE_SIZE_ERROR);
        }
        PageMethod.startPage(page, size);
        System.out.println(page + "                    " + size);
        List<Map<String, Object>> maps = examineApprovalMapper.selectByLikes(name, state, type, departmentName, creationTime, uploadPeopleName);
        for (Map<String, Object> map : maps) {
            Date creationTimes = (Date) map.get("creationTime");
            Date expirationDate = (Date) map.get("expirationDate");
            String creationTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(creationTimes);
            String expirationDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(expirationDate);
            map.put("creationTime", creationTimeFormat);
            map.put("expirationDate", expirationDateFormat);
        }
        return PageInfo.of(maps);
    }

    /**
     * 删除审批流程以及相关的流程节点的方法
     *
     * @param id 审批流程的id
     * @return 返回是否成功
     */
    @Override
    public Boolean deleteById(Long id) {
        //删除此审批流程所关联的流程节点
        FlowPathNode flowPathNode = new FlowPathNode();
        flowPathNode.setApprovalId(id);
        Integer integer = flowPathNodeMapper.delete(flowPathNode);
        //再删除此审批流程
        Integer integer1 = super.deleteById(id);
        // 返回是否成功
        return integer > 0 && integer1 > 0;
    }

    @Override
    public Boolean updateExamineApproval(Map<String, Object> map) throws BusinessException {
        //获取传递的参数中的id存不存在 不存在则抛异常
        if (map.get("id") == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        //创建一个审批流程对象用于装载数据
        ExamineApproval examineApproval = new ExamineApproval();
        examineApproval.setId(Long.valueOf(map.get("id").toString()));
        examineApproval.setName(map.get("name") != null ? map.get("name").toString() : null);
        examineApproval.setType(map.get("type") != null ? map.get("type").toString() : null);
        examineApproval.setExplain(map.get("explain") != null ? map.get("explain").toString() : null);
        //获取结束时间有点特殊 前端传递的是延长多少小时 所以需要进行时间转换
        Date date = null;
        if (map.get("expirationDate") != null) {
            Object countDate = redisTemplate.opsForValue().get("countDate");
            long expirationDate1 = Long.parseLong(map.get("expirationDate").toString());
            if (expirationDate1 > 72) {
                throw new BusinessException(ExceptionCode.TIME_ERROR);
            }
            Integer num = 0;
            if (countDate == null) {
                redisTemplate.opsForValue().set("countDate", expirationDate1);
            } else {
                redisTemplate.opsForValue().increment("countDate", expirationDate1);
                Object countDates = redisTemplate.opsForValue().get("countDate");
                num = Integer.valueOf(countDates.toString());
            }
            if (num > 72) {
                throw new BusinessException(ExceptionCode.TIME_ERROR);
            }
            long expirationDate = Long.parseLong(map.get("expirationDate").toString());
            Long time = System.currentTimeMillis() + (expirationDate * 60 * 60 * 1000);
            date = new Date(time);
        }
        examineApproval.setExpirationDate(date);
        Integer integer = super.updateById(examineApproval);
        return integer > 0;
    }

    @Override
    public void add(Map<String, Object> map) throws BusinessException {

        // 判断必填参数是否为空 如果有空则抛异常
        if (map.get("name") == null || map.get("type") == null || map.get("exUserId") == null || map.get("exOpinion") == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_ERROR);
        }
        //获取审批流程的数据传递给ExamineApproval对象
        ExamineApproval examineApproval = new ExamineApproval();
        examineApproval.setName(map.get("name").toString());
        examineApproval.setType(map.get("type").toString());
        examineApproval.setCreationTime(new Date());
        examineApproval.setUserId(Long.parseLong(map.get("exUserId").toString()));
        examineApproval.setState(0);
        examineApproval.setExplain(map.get("explain") != null ? map.get("explain").toString() : null);
        int exOpinion = Integer.parseInt(map.get("exOpinion").toString());

        examineApproval.setOpinion(exOpinion);
        //创建一个Date变量用于计算截止时间 (审批流程的截止时间)   (小时 * 60 * 60 * 1000 * 流程节点) + 当前时间戳
        Date dateTime;
        //创建一个Date变量用于计算截止时间 (流程节点的截止时间)   小时 * 60 * 60 * 1000 + 当前时间戳
        Date time;
        //如果传递的流程节点时间不为空
        Object fpnExpirationDate = map.get("fpnDate");
        if (fpnExpirationDate != null) {
            long fpnTime = Long.parseLong(fpnExpirationDate.toString());
            if (fpnTime > 72) {
                throw new BusinessException(ExceptionCode.TIME_ERRORS);
            }
            //计算流程节点的时间
            long milliseconds = (fpnTime * 60 * 60 * 1000);
            //计算审批流程截止时间
            long millisecond = (fpnTime * 60 * 60 * 1000) * exOpinion;
            //将当前时间+流程节点时间相加赋值给date
            time = new Date(System.currentTimeMillis() + milliseconds);
            dateTime = new Date(System.currentTimeMillis() + millisecond);
        } else {
            time = new Date(System.currentTimeMillis() + (48 * 60 * 60 * 1000));
            dateTime = new Date(System.currentTimeMillis() + (48L * 60 * 60 * 1000 * exOpinion));
        }
        examineApproval.setExpirationDate(dateTime);
        //执行添加操作
        examineApprovalMapper.insert(examineApproval);

        System.out.println("----------------------添加");
        System.out.println(examineApproval);
        System.out.println("----------------------添加");

        //获取流程节点管理员id的数组
        List<Integer> flowPathNodes = (List) map.get("fpnUserId");
        int size = flowPathNodes.size();
        if (exOpinion > 5) {
            throw new BusinessException(ExceptionCode.FLOW_PATH_NODE_ERROR);
        }
        if (size < exOpinion) {
            throw new BusinessException(ExceptionCode.EXAMINE_APPROVAL_OPINION_ERROR);
        }
        Object dateRemind = map.get("fpnRemind");

        //创建一个流程节点对象 用于判断添加后当前对象是否为空
        // FlowPathNode insert = null;

        //遍历添加流程节点
        for (Integer pathNode : flowPathNodes) {
            FlowPathNode flowPathNode = new FlowPathNode();
            flowPathNode.setApprovalId(examineApproval.getId());
            flowPathNode.setUserId(Long.valueOf(pathNode.toString()));
            flowPathNode.setState(false);
            flowPathNode.setExpirationDate(time);
            flowPathNode.setExpirationDateRemind(dateRemind != null ? Integer.parseInt(dateRemind.toString()) : null);
            //添加流程节点操作
            flowPathNodeMapper.insert(flowPathNode);
        }

    }

    @Override
    public void pass(Long id) throws BusinessException {
        if (id == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_NOT_NULL);
        }
        // 创建审批流程对象
        ExamineApproval examineApproval = new ExamineApproval();
        // 将参数赋值到此对象
        examineApproval.setId(id);
        // 进行查询得到另一个审批对象
        ExamineApproval examineApprovalS = super.selectById(examineApproval);

        // 将此对象的状态赋值为1 已通过
        examineApprovalS.setState(1);

        //进行修改操作
        Integer integer = super.updateById(examineApprovalS);

        //创建用户角色对象
        UserRole userRole = new UserRole();
        //将审批流程的上传人编号赋值给用户角色的用户编号
        userRole.setUId(examineApprovalS.getUserId());
        //获取查询到的审批流程对象的审批说明

        String explain = examineApprovalS.getExplain();
        //截取获得用户的最后一位
        String substring = explain.substring(explain.length() - 1);
        Long roleId = null;
        try {
            roleId = Long.parseLong(substring);
        } catch (NumberFormatException e) {
            throw new BusinessException(ExceptionCode.FORMAT_EXCEPTION);
        }

        //将截取的值赋值给角色编号
        userRole.setRId(roleId);

        int insert = userRoleMapper.insert(userRole);

        if (insert <= 0 || integer <= 0) {
            throw new BusinessException(ExceptionCode.FAILED_OPTION);
        }
    }

    @Override
    public void reject(Long id) throws BusinessException {
        if (id == null) {
            throw new BusinessException(ExceptionCode.ARGUMENTS_NOT_NULL);
        }
        ExamineApproval examineApproval = new ExamineApproval();
        // 将参数赋值到此对象
        examineApproval.setId(id);
        // 进行查询得到另一个审批对象
        ExamineApproval examineApprovalS = super.selectById(examineApproval);
        // 将此对象的状态赋值为2 已驳回
        examineApprovalS.setState(2);
        Integer integer = super.updateById(examineApprovalS);
        if (integer == null || integer <= 0) {
            throw new BusinessException(ExceptionCode.FAILED_OPTION);
        }
    }
}
